struct Header {
  char unknown_0000[44];
};

struct String {
  char value[];
};

struct InstStruct1 {
  char log_path[];
  char font[];
  char unknown_0100[14];
  String ui_strings_1[56];
};

// 0x00 Wise deflated file header
struct FileHeader {
  char unknown_2[2]; // 0x8000, 0x8100, 0x0000, 0x9800 0xA100
  u32 deflateStart;
  u32 deflateEnd;
  u16 date;
  u16 time;
  u32 inflatedSize;
  char unknown_20[20];
  u32 crc32;
  char filePath[];
  char fileText[];
  char terminator;
};

struct Unknown_0x03 {
  char unknown_1;
  char string_1[];
  char string_2[];
};

struct FormItem_0x04 {
  u8 no;
  char command_string_1[];
  // read this struct again until 'no' == 0 ???
};

struct Unknown_0x05 {
  // write .ini file?
  char file[];
  char heading[];
  char values[];
};

struct Unknown_0x06 {
  char unknown[6];
  u32 deflateStart;
  u32 deflateEnd;
  u32 inflatedSize;
  char terminator;
};

struct Unknown_0x07 {
  char unknown_1;
  char string_1[];
  char string_2[];

  if (unknown_1 == 0x02) {
    char string_3[];
  }
};

struct Unknown_0x08 {
  char unknown_1;
};

struct Unknown_0x09 {
  // 0x0901 and 0x0920 are different
  char unknown_1;
  if (unknown_1 != 0x01 && unknown_1 != 0x20) {
    char unknown_2;
  }
  char string_1[];
  char string_2[];
  char string_3[];
  char string_4[];
  if (unknown_1 == 0x01 || unknown_1 == 0x20) {
    char string_5[];
  }
};

struct Unknown_0x11 {
  char string_1[];
};

// Existing file on install medium (CD/DVD)
struct ExistingFile_0x12 {
  char unknown_1; // 0C
  char unknown_41[41];
  char from_path[];
  char unknown_string_1[];
  char unknown_string_2[];
  char to_path[];
};

struct Unknown_0x14 {
  u32 deflatedStart;
  u32 deflatedEnd;
  u32 inflatedSize;
  char name[];
  char message[];
};

struct Unknown_0x15 {
  char unknown_1;
  char string_1[];
  char string_2[];
};

struct TempFile_0x16 {
  char name[];
};

struct Unknown_0x17 {
  char unknown_1;
  char unknown_4[4];
  char string_1[];
};

struct Unknown_0x18 {
  // skip tailing zeros
};

struct Unknown_0x23 { // option?
  char unknown_1;
  char string_1[];
  char string_2[];
};

struct Unknown_0x31 {
  char unknown_1; // always 0x7F ?
  char string_1[];
};

struct Unknown_0x0A {
  char unknown_2[2]; // 0x0200
  char string_1[];
  char string_2[];
  char string_3[];
};

struct Unknown_0x0B {
  char unknown_1;
  char string_1[];
};

struct Unknown_0x0C {
  char unknown_1;
  char string_1[];
  char string_2[];
};

struct Unknown_0x1C {
  char string_1[];
};

struct Unknown_0x1E {
  char unknown_2[2];
};

struct Container {
  char op;

  match (op) {
    (0x00): FileHeader fileHeader;
    (0x03): Unknown_0x03 unknown_0x03;
    (0x04): FormItem_0x04 formItem;
    (0x05): Unknown_0x05 unknown_0x05;
    (0x06): Unknown_0x06 unknown_0x06;
    (0x07): Unknown_0x07 unknown_0x07;
    (0x08): Unknown_0x08 unknown_0x08;
    (0x09): Unknown_0x09 unknown_0x09;
    (0x11): Unknown_0x11 unknown_0x11;
    (0x12): ExistingFile_0x12 existingFile_0x12;
    (0x14): Unknown_0x14 unknown_0x14;
    (0x15): Unknown_0x15 unknown_0x15;
    (0x16): TempFile_0x16 tempFile_0x16;
    (0x17): Unknown_0x17 unknown_0x17;
    (0x23): Unknown_0x23 unknown_0x23;
    (0x0A): Unknown_0x0A unknown_0x0A;
    (0x0B): Unknown_0x0B unknown_0x0B;
    (0x0C): Unknown_0x0C unknown_0x0C;
    (0x1B): continue;
    (0x1C): Unknown_0x1C unknown_0x1C;
    (0x1E): Unknown_0x1E unknown_0x1E;
  }
};


/*

NAME          MD5                               FILE
----          ---                               ----
HL:CS  (CD)   43cd9aff74e04fa1b59321b898d9a6bd  counter-strike.exe
HLGOTY (CD)   f5b8b35ca02beeeb146e62a63a0273a6  SETUP.EXE
CS15          eedcfcf6545cef92f26fb9a7fdd77c42  csv15full.exe
RTCW   (CD)   f2d9e3e1eaaed66047210881d130384f  Setup.exe
ET            5cc104767ecdf0feb3a36210adf46a8e  WolfET.exe


Example:

// NOTE: Set absolute path to WISEINSTALL.hexpat
#include </home/user/code/WISESCRIPT.hexpat>

struct MainStruct {
  Header header;
  InstStruct1 install_struct_1;

  // HL:GOTY  6536
  // RTCW      403
  // HL:CS   29701
  // CS15     6253
  // ET        403
  Container items[390];
};

MainStruct mainStruct @0x0;
*/
